package com.marketlive.app.common.feature;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.validator.ValidatorResources;
import org.apache.struts.action.ActionServlet;
import org.apache.struts.action.PlugIn;
import org.apache.struts.config.ModuleConfig;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.xml.sax.SAXException;

public class FeatureInstanceValidation implements PlugIn
{
    private static Log         log = LogFactory.getLog(FeatureInstanceValidation.class);
    private ValidatorResources validatorResources;
    private String             pathNames;
    private boolean            stopOnFirstError;
    private String             code;
    private String             name;

    public void init(ActionServlet servlet, ModuleConfig config) throws ServletException {
        try {
            initResources(servlet);
            WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(servlet.getServletContext());
        }
        catch (Exception e) {
            log.error("Could load a validator resource from '" + this.pathNames + "':", e);
        }
    }

    public void destroy()
    {
        if (log.isDebugEnabled()) {
            log.debug("Destroying ValidatorPlugin");
        }

        this.validatorResources = null;
    }

    public String getPathNames()
    {
        return this.pathNames;
    }

    public void setPathNames(String pathNames)
    {
        this.pathNames = pathNames;
    }

    public boolean isStopOnFirstError()
    {
        return this.stopOnFirstError;
    }

    public void setStopOnFirstError(boolean stopOnFirstError)
    {
        this.stopOnFirstError = stopOnFirstError;
    }

    public String getCode()
    {
        return this.code;
    }

    public void setCode(String code)
    {
        this.code = code;
    }

    public String getName()
    {
        return this.name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public ValidatorResources getValidatorResources() {
        return this.validatorResources;
    }

    private void initResources(ActionServlet servlet)
            throws IOException, SAXException
    {
        String validationPath = getPathNames();

        if ((validationPath == null) || (validationPath.length() <= 0)) {
            return;
        }
        StringTokenizer st = new StringTokenizer(validationPath, ",");

        List streamList = new ArrayList();
        try {
            while (st.hasMoreTokens()) {
                String validations = st.nextToken().trim();

                InputStream input = servlet.getServletContext().getResourceAsStream(validations);

                if (input != null) {
                    BufferedInputStream bis = new BufferedInputStream(input);
                    streamList.add(bis);
                }
                else {
                    throw new IOException("Null validation rules file from '" + validations + "'.  Stream could not be opened.");
                }
            }

            int streamSize = streamList.size();
            InputStream[] streamArray = new InputStream[streamSize];
            for (int streamIndex = 0; streamIndex < streamSize; streamIndex++) {
                InputStream is = (InputStream) streamList.get(streamIndex);
                streamArray[streamIndex] = is;
            }

            this.validatorResources = new ValidatorResources(streamArray);
        }
        catch (SAXException e)
        {
            Iterator streamIterator;
            InputStream is;
            throw e;
        }
        finally {
            Iterator streamIterator = streamList.iterator();
            while (streamIterator.hasNext()) {
                InputStream is = (InputStream) streamIterator.next();
                is.close();
            }
        }
    }
}
